using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spinning.Spinning.Entity;
using Microsoft.Xna.Framework;
using Spinning.Spinning.Interface;
using Spinning.Spinning.Entity.Particle;
using Spinning.Spinning.Unitity;

namespace Spinning.Spinning.Level
{
    class EnemyLuncher : IUpdateHandler
    {
        public List<ParticleActor> ParticleActors { get; private set; }
        List<int> _timeSpan;
        List<int> _timeSpanBackup;
        PracticeScene _scene;
        float c;
        int particleCounter = 0;
        Random random = new Random();
        public bool Repeat { get; set; }
        int _min, _max;

        public EnemyLuncher(List<int> timeSpan, PracticeScene scene)
        {
            this._timeSpan = timeSpan;
            this._timeSpanBackup=new List<int>();
            _min = timeSpan.Min();
            _max = timeSpan.Max();
            _scene = scene;
            ParticleActors = new List<ParticleActor>();
            for (int i = 0; i < timeSpan.Count; i++)
            {
                Enemy enemy = new Enemy();
                enemy.textureName = "spinning";
                enemy.OnLoad();
                enemy.Style = 1;
                enemy.SetAnimation(Constants.playerAnimationFrame);
                enemy.OnCreatBody(_scene.World, _scene.PhysicConnectManager);
                enemy.BodyPosiotion = new Vector2(-2000-300*i, -2000);
                enemy.OnBeginContactEvent += onParticleContact;
                _scene.Attach(enemy);
                ParticleActors.Add(enemy);
            }

            foreach (int i in timeSpan)
                _timeSpanBackup.Add(i);
            Repeat = false;
        }

        public void OnUpdate(GameTime gameTime)
        {
            c += (float)gameTime.ElapsedGameTime.Milliseconds / 1000f;
            int counter = (int)c;

            if (_timeSpan.Contains(counter))
            {
                _timeSpan.Remove(counter);

                int shotCase = random.Next(3);
                int xMax = 0, yMax = 0, xMin = 0, yMin = 0;
                Vector2 v = new Vector2();
                switch (shotCase)
                {
                    case 0://top
                        xMin = 220;  //20
                        xMax = 260;  //460
                        yMin = yMax = -100;
                        break;
                    case 1://right
                        xMin = xMax = 480 + 100;
                        yMin = -50;  //-100
                        yMax = 150;  //250
                        break;
                    case 2://left
                        xMin = xMax = -100;
                        yMin = -50;  //-100
                        yMax = 150;  //150
                        break;
                }

                int pX = random.Next(xMin, xMax);
                int pY = random.Next(yMin, yMax);
                Vector2 pos = new Vector2(pX, pY);

                float nv = ((float)random.Next(45, 90)) / 5f;
                v = get_UnitV_ByActor(_scene.Player, pos)*nv;
                int a = 25;
                float aX = ((float)random.Next(-a, a)) /20f;
                float aY = ((float)random.Next(0, a)) /10f;
                Vector2 acc = new Vector2(aX,aY);

                shotParticle(pos, v,acc);
            }

            if (counter > _max && Repeat) {
                c = 0;
                _timeSpan.Clear();
                foreach (int i in _timeSpanBackup)
                    _timeSpan.Add(i);
            }

        }

        private void shotParticle(Vector2 pos, Vector2 vec,Vector2 acc)
        {
            if (ParticleActors.Count > 0)
            {
                ParticleActor e = ParticleActors[particleCounter];
                e.Reset();
                e.ParticlePosition = pos;
                e.Velocity = vec;
                e.Acceleration = acc;
                particleCounter=(particleCounter+1)%ParticleActors.Count;
            }
        }

        private Vector2 get_UnitV_ByActor(Actor entity, Vector2 pos)
        {
            int offset = 35;
            Vector2 v = entity.Position - pos + new Vector2(random.Next(-offset, offset), random.Next(-offset, offset));
            v.Normalize();

            return v;
        }

        void onParticleContact(PhysicSprite me, PhysicSprite _other)
        {
            Actor other = (Actor)_other;
            if (other.Physic_Type == Spinning.Entity.Actor.PhysicType.Player ||
                other.Physic_Type == Spinning.Entity.Actor.PhysicType.Enemy || 
                other.Physic_Type == Spinning.Entity.Actor.PhysicType.Marble)
            {
                ParticleActor e = (ParticleActor)me;
                e.isMotor = false;
                if (other.Physic_Type == Spinning.Entity.Actor.PhysicType.Player)
                    e.isHit = true;
            }
        }

    }
}
